/**
 * @particulars 对数据进行依赖收集
 * Dep 和 Watcher 是一个多对多的关系：
 *  一个属性可以在多个组件中使用，一个Dep => 多个Watcher
 *  一个组件中会有多个属性，一个Watcher => 多个Dep
 */

let id = 0;

class Dep {
  constructor() {
    // 为每个Dep 添加唯一的标识
    this.id = id++;
    // 收集存放当前属性对应的Watcher
    this.subs = [];
  }

  depend() {
    // 1、不重复收集Watcher，同时Watcher 需要记录对应的Dep
    Dep.target.addDep(this);
  }

  addSub(watcher) {
    // 2、Dep 收集对应Watcher
    this.subs.push(watcher);
  }

  notify() {
    // 3、属性变化了，对应的Dep 通知Watcher 更新视图
    // 一个值可能会有多次更新操作，但是Watcher 的update 被维护在异步队列里面执行，保证视图就更新一次
    this.subs.forEach(watcher => watcher.update());
  }
}

// 在Dep 上添加一个全局静态属性，便于存储对应的Watcher
Dep.target = null;

// 存储所有的Watcher，利用栈去操作对应的Watcher
const stack = [];

// 进栈，target 指向当前watcher
export function pushTarget(watcher) {
  stack.push(watcher);
  Dep.target = watcher;
}

// 出栈，target 指向栈内最后的watcher
export function popTarget() {
  stack.pop();
  Dep.target = stack.at(-1);
}

export default Dep